//
// Created by 17775 on 2024/6/25.
//

#ifndef RAYCI_LIVEMODE_2D_VIEW_H
#define RAYCI_LIVEMODE_2D_VIEW_H

#include <QWidget>
#include "../qcustomplot.h"
#include "../Common/SurfaceGraph.h"
#include "../Common/crosssection.h"
#include "../Common/centroiddistances.h"
#include "../Common/powerprofile.h"
#include "../Common/threed_view.h"
#include "../utils/RayCiDataReceiveListener.h"
#include "../Common/aoisetting.h"
#include "../Common/beamprofilerdynamic.h"
#include "livemode_2d_view_settings.h"
// #include  "../RayCiLut.hpp"
#include "../common/commonlutwidget.h"


struct AOI;
using namespace Qt::StringLiterals;

QT_BEGIN_NAMESPACE
namespace Ui { class LiveMode_2D_View; }
QT_END_NAMESPACE

class LiveMode_2D_View : public QDockWidget, public RayCiDataReceiveListener {
Q_OBJECT
public:
    enum class MousePos {
        Top,
        Bottom,
        Left,
        Right,
        LeftTop,
        LeftBottom,
        RightTop,
        RightBottom
    };

signals:
    void startMeasurement(int index);
    void startSnapshot();
    void _2DImageMapSizeChanged(double nX, double nY);
    void liveModeIsSelected();
    void closeLiveModeWindows();
    void updateEllipse(double x, double y, double radiusX, double radiusY, double angle,int index);
    void updateCircle(double x, double y, double radius);
    void updateArbitrary(double dX1, double dY1, double dX2, double dY2);
    void showAOISelection();
    void showBeamResult();
    void showPowerProfile();
    void showHistogram();
    void showBeamProfilerDynamic();
    void show3D_View();
    void showCrossSection();
    void showCentroidDistances();
    void show2DViewSetting();
    void getCurrentY(double currentY, double nY);
    void setCrossPos(double pos);
    void setCrossAngle(double angle);
    void setAutoContrast(bool isAuto);

    void mainAOIChanged(int index);
    void Show_Or_Hide_Aoi(int index,bool show);
    void Live2DModeViewClicked();

private slots:
    void onMousePress(const QMouseEvent *event);
    void onMouseMove(const QMouseEvent *event);
    void onMouseRelease(const QMouseEvent *event);

    // AOI管理相关槽函数
    void handleShowOrHideAoi(int index, bool show);
    void handleMainAOIChanged(int index);
    void mousePressEvent(QMouseEvent *event);


public slots:
    // AOI椭圆实时更新槽函数
    void updateAOIEllipseFromModel(const AOI& aoiData);
private:
    Ui::LiveMode_2D_View *ui;
    LiveMode_2D_View_Settings *m_settings = nullptr;
    bool isVisible = false;
    void resizeEvent(QResizeEvent *event) override;
    QMenu *m_contextMenu = nullptr;
    QCPItemLine *centerHLine = nullptr;
    QCPItemLine *centerVLine = nullptr;
    bool isDraggingXCrossSectionLine = false;
    QCPItemLine *crossSectionLine = nullptr;
    QCPItemText *crossSectionText = nullptr;
    QCPItemEllipse *crossSectionCircle = nullptr;
    QCPItemPixmap *imageItem = nullptr;
    std::vector<float> _vecData;
    std::mutex mutex;
    float getDataAt(int x, int y);
    std::atomic<bool> getFloatThreadThreadRunning = false;
    std::thread showFloatThread;
    void setLineCircleVisible(bool showLine);
    //AOI相关操作
    QMenu* m_pAOIMenu;
    QVector<QAction*> m_aoiActions;
    QVector<bool> m_aoiStates; // 存储AOI的选中状态
    int m_mainAOIIndex = 0; // 主AOI索引，默认0（第一个AOI）
    void initAOIStates(); // 初始化AOI状态
    void createAOILabel(int index, QCPCurve *ellipseCurve);

//    void showFloatData();
//    int xPos = 0;
//    int yPos = 0;

protected:
    QCustomPlot *_2DImagePlot = nullptr;
    QCPColorMap *colorMap = nullptr;
    void set2DMapArea();
    void initCoordinateSystem();
    // void initLUTWidget();
    // void updateLUTDisplay();
//    QCPItemText *coordinateLabel = nullptr;
    QCPCurve *ellipse = nullptr;
    QCPCurve *fittingEllipse = nullptr;
    QCPCurve *powerProfileEllipse = nullptr;
    QCPItemLine *hArrow = nullptr;
    QCPItemLine *vArrow = nullptr;
    QPointF lastMousePos;
    void closeEvent(QCloseEvent *event) override;
    static double calculateDistanceToCurveBoundary(QCPCurve *ellipseCurve, const QPointF &mousePos, const QPointF &center, double major, double minor, double azimuthAngle);
    static double calculateDistanceToEllipseBoundary(QCPItemEllipse *ellipse, const QPointF &mousePos) ;
    enum DraggingEndpoint {
        None,
        StartPoint,
        EndPoint
    } draggingEndpoint;
    QPointF dragStartPos;
    static double calculateTwoPointDistance(const QPointF &p1, const QPointF &p2);
    static double calculateDistanceToCrossSectionLine(const QPointF &p, const QPointF &a, const QPointF &b);
    static QPointF rotatePoint(const QPointF &point, double angle);
    QList<QCPCurve*> ellipses;
    QCPCurve *activeEllipse;
    QCPCurve *m_currentOperatingEllipse = nullptr; // 当前正在操作的椭圆
    int m_currentOperatingEllipseIndex = -1; // 当前正在操作的椭圆索引

    // 椭圆参数存储
    struct EllipseParams {
        QPointF center;
        double major = 0;
        double minor = 0;
        double azimuthAngle = 0;
    };
    QList<EllipseParams> ellipseParams;
    int m_previousMainAOIIndex = 0; // 记录操作前的主AOI索引
    bool nearEllipseEdge = false;
    bool mouseIsMoving = false;
    QPointF crossCenter;
    double lastAngle = 0;
    bool crossIsRotating = false;
    bool crossStartEnding = false;
    bool crossCircleIsMoving = false;
    bool bFirst = true;
    bool bFirstAOIUpdate = true;
    const double threshold = 5.0;
    QList<QCPItemText*> aoiLabels;  // 存储AOI标签
    // QLabel* m_lutLabel = nullptr;
    // QList<QLabel*> m_scaleLabels;
    CommonLutWidget *m_lutWidget = nullptr;

public:
    explicit LiveMode_2D_View(LiveMode_2D_View_Settings *settings = nullptr, QWidget *parent = nullptr);
    ~LiveMode_2D_View() override;
    void btnMeasurement_Click();
    void btnSnapshot_Click();
    void btnBeamResults_Click();
    void btnAOISelection_Click();
    void btnAdjustCS_Click();
    void btn3D_View_Click();
    void btnCross_Section_Click();
    void btnCentroid_Click();
    void btnPower_Profile_Click();
    void btnHistogram_Click();
    void btn_BeamProfiler_Dynamic_Click();
    void receiveMessage(const std::shared_ptr<LiveModeFloatData<std::vector<float>>>& msg) override;
    void processCCDImageData(const std::shared_ptr<QPixmap>& pixmap) const;
    void processFloatData(std::shared_ptr<std::vector<float>> &vecData);

    void updateCoords(bool isXImageOrAOI, int index);
    void updateCoordsPos(bool isLeftOrTop, int index);

    // powerProfile
    void paintCenterPos(double x_center, double y_center) const;
    void hideCenterPos() const;
    void hidePowerProfileEllipse();
    void paintPowerProfileEllipse(double x_center, double y_center, double major, double minor);

    // CrossSection
    double preXPos = 0, preYPos = 0, preX1 = 0, preY1 = 0, preX2 = 0, preY2 = 0, preX = 0, preY = 0, preRadius = 0;
    double prevArrowStartX = 0, prevArrowStartY = 0, prevArrowEndX = 0, prevArrowEndY = 0, preHArrowStartX = 0, preHArrowStartY = 0, preHArrowEndX = 0, preHArrowEndY = 0;
    bool bXImageOrAOI = true, bYImageOrAOI = true;
    int xIndex = 0, yIndex = 0;
    void paintXCrossSection(double y_pos);
    void paintYCrossSection(double x_pos);
    void paintRadialSection(double y_pos);
    void drawClippedLine(double x_center, double y_center, double angle, double x_min, double x_max, double y_min, double y_max);
    void paintArbitrarySection(double dX1, double dY1, double dX2, double dY2);
    void paintCrossCircle(double dX, double dY, double dRadius);
    void initEllipses(double dPositionX_px, double dPositionY_px, double dMajor_px, double dMinor_px) const;
    void updateFittingEllipses(double dPositionX_px, double dPositionY_px, double dMajor_px, double dMinor_px, double angle);
    void setImageSize() const;
    void checkAuto(bool isChecked);
    void setCrossCenterPos(double xPos, double yPos);

    std::shared_ptr<LiveModeFloatData<std::vector<float>>> storedData;

    int getOrder() const override {
        return 100;
    }
    int crossSectionType = 0;
    double angle = 0;
    void setWindowTitleName(const QString& name);

    void updateAOILabels();
    void onAOIActionTriggered(QAction *action);
    void setMainAOI(int index);
    // 用于创建或显示AOI椭圆
    QCPCurve* createOrShowAOIEllipse(int index, bool createIfNotExists = true);

    // 椭圆计算和绘制相关函数
    static void updateEllipseCurve(QCPCurve *curve, const QPointF &center, double major, double minor, double azimuthAngle);
    QPointF getEllipseCenter(int index) const;
    EllipseParams getEllipseParams(int index) const;
    void setEllipseParams(int index, const EllipseParams &params);
    Qt::CursorShape getCursorShapeForPosition(const QPointF &mousePos, const EllipseParams &params) const;
    //用于更新AOI的可见性
    void updateAOIVisibility(int index, bool show);



    static int nSizeX, nSizeY;

};


#endif //RAYCI_LIVEMODE_2D_VIEW_H
